package me.zhengjie.timing.plc;

import lombok.RequiredArgsConstructor;
import me.zhengjie.WcsReport.WcsReportService;
import me.zhengjie.agvSend.AgvSendService;
import me.zhengjie.pojo.dto.AgvTaskSubmitDto;
import me.zhengjie.pojo.dto.TargetRoute;
import me.zhengjie.pojo.entity.WcsFluentFrameConfig;
import me.zhengjie.pojo.entity.WcsOutboundMission;
import me.zhengjie.pojo.vo.EmptyContainer;
import me.zhengjie.pojo.vo.ReturnVo;
import me.zhengjie.sqlservice.*;
import me.zhengjie.tcp.FluentFrameTCPA;
import me.zhengjie.tcp.FluentFrameTCPB;
import me.zhengjie.util.state.MaterialStatus;
import me.zhengjie.util.state.TaskStatus;
import me.zhengjie.util.state.TaskType;
import me.zhengjie.utility.IdWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Component
@RequiredArgsConstructor
public class FluentFrameSingleLayerTiming {
    private static final Logger fluentFrame = LoggerFactory.getLogger("fluentFrame");

    private final WcsFluentFrameConfigService wcsFluentFrameConfigService;

    private final FluentFrameTCPA fluentFrameTCPA;

    private final FluentFrameTCPB fluentFrameTCPB;

    private final WcsReportService wcsReportService;

    private final WcsInboundMissionSqlService wcsInboundMissionService;

    private final AgvSendService agvSendService;

    private final WcsOutboundMissionService wcsOutboundMissionService;

    private final IdWorker idWorker;

    private final WcsFluentFrameOutboundDetailsService wcsFluentFrameOutboundDetailsService;

    private final WcsFluentFrameOutboundDetailsHistoryService wcsFluentFrameOutboundDetailsHistoryService;

    @Transactional
//    @Scheduled(fixedDelay = 10000)
    public void fluentFrameSingleLayer() {
        //查询所有流利架
        List<WcsFluentFrameConfig> wcsFluentFrameConfigList = wcsFluentFrameConfigService.selectSingLayer(1);
        if (!wcsFluentFrameConfigList.isEmpty()) {
            for (WcsFluentFrameConfig wcsFluentFrameConfig : wcsFluentFrameConfigList) {
                Integer id = wcsFluentFrameConfig.getId();
                Integer size = wcsFluentFrameConfig.getSize();
                String region = wcsFluentFrameConfig.getRegion();
                Integer outboundStorageSizeAddress = wcsFluentFrameConfig.getOutboundStorageSizeAddress();
                Integer unitId = wcsFluentFrameConfig.getUnit_id();
                Integer threeReturnResult = wcsFluentFrameConfig.getThreeReturnResult();
                if (TaskType.FLUENT_FRAME_A.getMessage().equals(region)){
                    //查询流利架数量
                    Integer quantity = fluentFrameTCPA.readHoldingRegisters(outboundStorageSizeAddress, unitId);
                    //单层流利架
                    Integer storageSize = 4;
                    storageSize = storageSize - size - quantity;
                    if (storageSize >= 2) {
                        //单层流利架有二个储位时需要补空箱
                        for (Integer i = 0; i < storageSize; i++) {
                            //todo 发送空箱终点储位申请
                            String storageRegion = wcsFluentFrameConfig.getStorageRegion();
                            String destination = wcsFluentFrameConfig.getStorageCode();
                            ReturnVo returnVo = wcsReportService.emptyContainer(storageRegion);
                            if (returnVo.getCode() == 200) {
                                EmptyContainer emptyContainer = (EmptyContainer) returnVo.getData();
                                String outboundCode = String.valueOf(idWorker.nextId());
                                //容器编码
                                String containerCode = emptyContainer.getContainerCode();
                                //起点位置
                                String source = emptyContainer.getStorageCode();

                                //000 0 0000
                                AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
                                //todo 任务类型，根据现场情况来定
                                agvTaskSubmitDto.setTaskType(TaskType.PF_FMR_COMMON.getMessage());
                                ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
                                TargetRoute targetRoute = new TargetRoute();
                                TargetRoute targetRoutes = new TargetRoute();
                                //添加起点
                                targetRoute.setSeq(0);
                                targetRoute.setType(TaskType.STORAGE.getMessage());
                                targetRoute.setCode(source);
                                //添加终点
                                targetRoutes.setSeq(1);
                                targetRoutes.setType(TaskType.SITE.getMessage());
                                targetRoutes.setCode(destination);
                                targetRouteList.add(targetRoute);
                                targetRouteList.add(targetRoutes);
                                agvTaskSubmitDto.setTargetRoute(targetRouteList);
                                agvTaskSubmitDto.setRobotTaskCode(outboundCode);
                                agvTaskSubmitDto.setInitPriority(99);
                                String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
                                //todo 生成出空箱任务，发给AGV
                                if (taskCode !=null) {
                                    fluentFrameTCPA.writeWithRetry(threeReturnResult, MaterialStatus.AGV_TRANSPORT_IN_THE_TASK.getStatus(),unitId,MaterialStatus.RETRY_COUNT.getStatus());
                                    //修改数量
                                    size++;
                                    wcsFluentFrameConfigService.updateSize(id,size);
                                    //生成出库任务
                                    WcsOutboundMission wcsOutboundMission = new WcsOutboundMission();
                                    wcsOutboundMission.setOutboundCode(outboundCode);
                                    wcsOutboundMission.setMissionStatus(TaskStatus.task_send.getStatus());
                                    wcsOutboundMission.setContainerCode(containerCode);
                                    wcsOutboundMission.setSource(source);
                                    wcsOutboundMission.setDestination(destination);
                                    wcsOutboundMission.setCreateTime(LocalDateTime.now());
                                    wcsOutboundMission.setUpdateTime(LocalDateTime.now());
                                    wcsOutboundMission.setContainerType(TaskType.EMPTY_MATERIAL_BOX.getStatus());
                                    wcsOutboundMission.setPriority(90);
                                    wcsOutboundMission.setIsNest(0);
                                    boolean b = wcsOutboundMissionService.insertOutbound(wcsOutboundMission);
                                    if (!b) {
                                        fluentFrame.error("数据库异常，添加出库任务失败");
                                        throw new RuntimeException("数据库异常，添加出库任务失败");
                                    }
                                }
                            }
                        }
                    }
                }else if (TaskType.FLUENT_FRAME_B.getMessage().equals(region)){}
            }
        }
    }
}
